/*
 * GASimulation.cpp
 *
 *  Created on: Apr 9, 2012
 *      Author: lfelipe
 */

#include <iostream>
#include <math.h>
#include <stdlib.h>

#include "GASimulation.h"
#include "RandomNumber.h"
#include "Instance.h"
#include "../Model/GeneticAlgorithm.h"
#include "../Boundary/InstanceLayerDefault.h"
#include "../Boundary/Config.h"
#include "../Model/EvaluationFunction.h"
#include "../Model/FiEvaluationFunction.h"
#include "../Model/TetaEvaluationFunction.h"

GASimulation::GASimulation()
{
}

GASimulation::~GASimulation()
{
    // TODO Auto-generated destructor stub
}

void GASimulation::execute(int argc,char *argv[])
{
    if(argc < 8){
        std::cout << "Faltam argumentos: \n: ./GAQCA numero_de_individuos numero_de_iteracao populacao_crossover populacao_mutacao taxa_de_crossover taxa_de_mutacao semente instancia evaluation_function";
    } else {
        int num_individuos = atoi(argv[1]);
        int num_iteracoes = atoi(argv[2]);
        int populacao_crossover = atoi(argv[3]);
        int populacao_mutacao = atoi(argv[4]);
        float taxa_crossover = atof(argv[5]);
        float taxa_mutacao = atof(argv[6]);
        int semente = atoi(argv[7]);

        RandomNumber::get_instance(semente);

        InstanceLayerDefault instance_reader;
        Instance instance = instance_reader.readInstanceWithLayerDefault(Config::get_instance().get_config_string("INSTANCES_PATH") + argv[8]);

        int evaluation_function = atoi(argv[9]);
        EvaluationFunction * function = NULL;
        switch (evaluation_function) {
        case 1:
            function = new FiEvaluationFunction();
            instance.set_evaluation_funcion(function);
            break;
        case 2:
            function = new TetaEvaluationFunction();
            instance.set_evaluation_funcion(function);
            break;
        default:
            break;
        }

        GeneticAlgorithm algorithm(&instance,num_individuos,num_iteracoes);

        std::cout << instance.get_layer_default()->print_layer() << std::endl;

        algorithm.set_layer_default(instance.get_layer_default());
        algorithm.set_crossover_tax(taxa_crossover);
        algorithm.set_mutation_tax(taxa_mutacao);
        algorithm.set_population_crossover_size(populacao_crossover);
        algorithm.set_population_mutation_size(populacao_mutacao);
        algorithm.set_population_reproduction_size(num_individuos - populacao_crossover - populacao_mutacao);
        algorithm.set_simulation(this);
        for (int i = semente; i < semente+1; ++i) {
            RandomNumber::change_seed(i);
            this->create_folder();
            algorithm.execute();
            algorithm.clear_execution();
            clear_simulation();
        }

        RandomNumber::delete_instance();
        delete instance.evaluation_function();
        Config::delete_instance();

    }
}



